package main

import "strconv"

// 方法声明
// func关键词 方法名 (参数列表) (返回值列表)
// 方法签名Signature=方法名+参数列表+返回值列表
// 方法名首字母大小写决定了方法的作用域(导出方法/内部方法)

func main() {
	//方法名首字母的大小写,决定了方法的作用域
	println(innerFunc("hello"))
	println(ExportedFunc("hello"))

	//接收方法的多返回值
	res, err := namedMultiReturnsFunc("hello")
	println(res, err)

	//可以使用_占位符,忽略方法的返回值
	res, _ = namedMultiReturnsFunc("hi!")
	println(res)

	//不定参数
	sum := add("zsa", 1, 2, 3, 4)
	println(sum)

	//不定参数也可以不传值
	sum = add("zsa1")
	println(sum)

	//递归方法,可能会导致栈溢出
	//recursive()
}

// 私有方法,包内可访问
func innerFunc(name string) string {
	return "Inner Function: " + name
}

// ExportedFunc 导出方法,包外可访问
func ExportedFunc(name string) string {
	return "Exported Function: " + name
}

// 多返回值的方法
func multiReturnsFunc(name string) (string, error) {
	return "Multi Returns Func: " + name, nil
}

// 具名的多返回值方法
func namedMultiReturnsFunc(name string) (res string, err error) {
	//带名字的返回值,相当于声明了一个在整个方法声明作用域内的局部变量,会无形中扩大返回值的作用域
	res = "Named Multi Returns Func: " + name
	return res, nil
}

// 递归方法,可能会导致栈溢出: fatal error: stack overflow
func recursive() {
	recursive()
}

// 不定参数方法
// 不定参数用...标识,且必须放在入参的最后一个
// 不定参数在内部会被作为slice切片处理
// Option模式大量使用了不定参数
func add(name string, items ...int) string {
	sum := 0
	for _, i := range items {
		sum += i
	}
	return name + ": sum = " + strconv.Itoa(sum)
}
